/*
 * Kernel.c - Mokri
 * Contributors: xMine, pharno
 * (Any new Contributor may add himself/herself to the list)
 * 
 * TODO Liste
 * - Große Dateien im Ext2 Treiber
 */

#include <main.h>
#include <structs.h>
#include <memory.h>
#include <print.h>
#include <paging.h>
#include <gdt.h>
#include <idt.h>
#include <scheduler.h>
#include <rtc.h>
#include <keyboard.h>
#include <panic.h>
#include <fs.h>
#include <fs_dev.h>
#include <fdc.h>
#include <input.h>
#include <elf.h>
#include <vga.h>
// Dateisysteme
#include <ext2.h>

volatile char *videoram = (char*) VRAM_POS; // Wird von print.c und vga.c benötigt

void task_kernel (); // Kernel Task
void task_leerlauf ();
void shortcut_handler (struct keyboard_struct *);

/** Notiz:
    Wenn nun Code getestet wird bitte auf jeden Fall in der task_kernel Funktion!!
 **/
int main (struct multiboot_info *mb_info) {

	clearscreen ();

	// Alles mögliche initialisieren und starten
	gdt_init ();
	idt_init ();
	mt_init ();
	pmm_init (mb_info);
	vga_init ();
	keyboard_init ();
	fs_init ();
	fs_add_node ("/", FS_FLAG_FOLDER, NULL, 0); // Stammverzeichniss hinzufügen
	
	fs_announce_driver (dev_init, dev_open, dev_close, dev_read, dev_write, NULL,
			    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, dev_deinit);
	
	#if 1
	paging_init(mb_info->mbs_mem_lower+mb_info->mbs_mem_upper);
	#endif
	
	vga_hide_cursor (); 
	
	printf ("Wir haben den %i.%i.%i und es ist %02i:%02i:%02i\n",
		rtc_day(), rtc_month(), rtc_year(),
		rtc_hours(), rtc_minutes(), rtc_seconds());
	
	keyb_add_handler (shortcut_handler);
	struct task *leerlauf = mt_createThread (task_leerlauf, FALSE);
	struct task *kernel = mt_createThread (task_kernel, FALSE); // Kernel Task starten
	
	leerlauf->sf->cs = kernel->sf->cs = 8; // Die Codesegmente der beiden Tasks auf Ring0 setzen
	leerlauf->running = kernel->running = TRUE;
	
	while (1) { } // Das nennt man Leerlaufprozess *hust*

	return 0;
}

void task_leerlauf () { // Leerlauf Prozess
	while (1) {
		floppy_timer (); // Damit wird nach einiger Zeit der Floppy Motor abgeschaltet
	}
}

void task_kernel () {
	
	print ("Starte Floppy... ");
	if (!floppy_init ()) {
		kernel_panic ("Konnte den Floppy Treiber nicht starten!");
	}
	print ("OK\n");
	
	ext_start ("/dev/fd"); // Ext2 Treiber starten
	
	
	pid_t konsole = elf_load ("/env.elf");
	if (konsole > 0) {
		ResumeTask (konsole);
	} else {
		printf ("Konnte console.elf nicht ausfuehren!");
	}
	
	while (1) {
		// <Insert sinnlose Rechnung here>
	}
}

/* Kümmert sich um Systemweite Shortcuts
 */
void shortcut_handler (struct keyboard_struct *keyb) {
	if (keyb->pressed && keyb->key_ralt) {
		char code = keyb->code;
		
		if (code >= 0x3B && code <= 0x3E) { // F1 bis F4 (F10 = 0x44)
			print ("Wechsele Schirm...\n");
			vga_set_page ( (uint32_t)(code-0x3B) ); // Angezeigte Seite ändern
			printf ("Bildschirmseite %u\n", (uint32_t)(code-0x3B));
			
			keyb->input = 0x0;
		}
		
		if (keyb->input == 'c') {
			clearscreen ();
			keyb->input = 0x0; // Damit senden wir das Zeichen nicht weiter
		}
	}
}
